/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.ee.cybertron.energon.base;

import java.io.Serializable;
import java.util.ArrayList;
import javax.persistence.*;

/**
 *
 * @author stevenziggiz
 */
public class ServicioBase implements Serializable {

    private static EntityManagerFactory ENTITY_MANAGER_FACTORY =
            Persistence.createEntityManagerFactory("persistenceUnit");

    private EntityManager obtieneEntityManager() {
        return ENTITY_MANAGER_FACTORY.createEntityManager();
    }

    public ServicioBase() {
    }

    public void guardar(Object elemento) throws RuntimeException {
        EntityManager entity_manager = null;
        EntityTransaction entity_transaction = null;
        try {
            entity_manager = obtieneEntityManager();
            entity_transaction = entity_manager.getTransaction();
            entity_transaction.begin();
            entity_manager.persist(elemento);
            entity_transaction.commit();
            entity_manager.clear();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (entity_manager != null && entity_manager.isOpen()) {
                entity_manager.close();
            }
        }
    }

    public <T> ArrayList<T> seleccionar(Class clase) {
        EntityManager em = obtieneEntityManager();
        Query query = em.createQuery("Select p FROM " + clase.getSimpleName() + " as p");
        return (ArrayList<T>) query.getResultList();
    }

    public <E> ArrayList<E> seleccionar(Class clase, int desde, int hasta) throws RuntimeException {
        EntityManager entity_manager = null;
        try {
            entity_manager = obtieneEntityManager();
            Query q = entity_manager.createQuery("select object(o) from " + clase.getSimpleName() + " as o");
            q.setMaxResults(hasta - desde);
            q.setFirstResult(desde);
            return (ArrayList<E>) q.getResultList();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (entity_manager != null && entity_manager.isOpen()) {
                entity_manager.clear();
                entity_manager.close();
            }
        }
    }

    public <E> ArrayList<E> seleccionar(String named_query, Object... parametros) throws RuntimeException {
        EntityManager entity_manager = null;
        try {
            entity_manager = obtieneEntityManager();
            Query q = entity_manager.createNamedQuery(named_query);
            for (int i = 0; i < parametros.length; i++) {
                q.setParameter(i + 1, parametros[i]);
            }
            return (ArrayList<E>) q.getResultList();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            if (entity_manager != null && entity_manager.isOpen()) {
                entity_manager.clear();
                entity_manager.close();
            }
        }
    }

    public Object obtenerElemento(String named_query, Object... parametros) throws RuntimeException {
        EntityManager entity_manager = null;
        try {
            entity_manager = obtieneEntityManager();
            Query q = entity_manager.createNamedQuery(named_query);
            for (int i = 0; i < parametros.length; i++) {
                q.setParameter(i + 1, parametros[i]);
            }
            return q.getSingleResult();
        } catch (Exception e) {
            if (e instanceof NoResultException) {
                return null;
            }
            throw new RuntimeException(e);
        } finally {
            if (entity_manager != null && entity_manager.isOpen()) {
                entity_manager.clear();
                entity_manager.close();
            }
        }
    }

    public boolean executeQuery(String nativeQuery) throws RuntimeException {
        EntityManager entity_manager = null;
        EntityTransaction entity_transaction = null;
        try {
            entity_manager = obtieneEntityManager();
            entity_transaction = entity_manager.getTransaction();
            entity_transaction.begin();
            Query q = entity_manager.createNativeQuery(nativeQuery);
            q.executeUpdate();
            entity_transaction.commit();
            return true;
        } catch (Exception e) {
            return false;
        } finally {
            if (entity_manager != null && entity_manager.isOpen()) {
                entity_manager.clear();
                entity_manager.close();
            }
        }
    }

    public Object executeQueryR(String nativeQuery, Class clase) throws RuntimeException {
        Query q;
        Object result = null;
        EntityManager entity_manager = null;
        EntityTransaction entity_transaction = null;
        try {
            entity_manager = obtieneEntityManager();
            entity_transaction = entity_manager.getTransaction();
            entity_transaction.begin();
            if (clase == null) {
                q = entity_manager.createNativeQuery(nativeQuery);
            }else{
                q = entity_manager.createNativeQuery(nativeQuery, clase);
            }
            result = q.getSingleResult();
            entity_transaction.commit();
            return result;
        } catch (Exception e) {
            return result;
        } finally {
            if (entity_manager != null && entity_manager.isOpen()) {
                entity_manager.clear();
                entity_manager.close();
            }
        }
    }
}
